package array;

import java.util.*;
import java.util.stream.Collectors;

public class DeviceMgtSys {
    // 进程容器
    Map<String, Process> allProcessMap;

    Map<Integer, Device> deviceMap;

    DeviceMgtSys(int processNum, int maxMenSize) {
        allProcessMap = new HashMap<>();
        deviceMap = new HashMap<>();

        for (int i = 1; i <= 3; i++) {
            for (int j = 0; j < processNum; j++) {
                Process process = new Process();
                process.processId = j;
                process.processGroupType = i;
                process.uniqueId = UUID.randomUUID().toString();
                process.maxMenSize = maxMenSize;
                process.freeMenSize = maxMenSize;
                allProcessMap.put(process.uniqueId, process);
            }
        }
    }

    int createDevice(int deviceId, int deviceType, int memSize) {
        // 根据负载均衡原则找出最符合的一个进程
        List<Process> usedProcessList = allProcessMap.values().stream().filter(v -> v.processGroupType == deviceType).collect(Collectors.toList());
        Process lastProcess = usedProcessList.stream().sorted(Comparator.comparing(Process::getFreeMenSize).thenComparing(Comparator.comparing(Process::getProcessId).reversed())).collect(Collectors.toList()).get(usedProcessList.size() - 1);

        if (lastProcess.freeMenSize < memSize) {
            return -1;
        }

        // 更新此进程
        lastProcess.freeMenSize = lastProcess.freeMenSize - memSize;
        allProcessMap.put(lastProcess.uniqueId, lastProcess);

        // 由于设备id唯一，建立设备与进程映射
        Device device = new Device();
        device.deviceId = deviceId;
        device.deviceType = deviceType;
        device.memSize = memSize;
        device.processUniqueId = lastProcess.uniqueId;
        device.processId= lastProcess.processId;
        deviceMap.put(deviceId, device);

        return lastProcess.processId;
    }

    boolean deleteDevice(int deviceId) {
        if (!deviceMap.containsKey(deviceId)) {
            return false;
        }

        Device device = deviceMap.get(deviceId);

        Process process = allProcessMap.get(device.processUniqueId);
        process.freeMenSize = process.freeMenSize + device.memSize;
        allProcessMap.put(process.uniqueId, process);
        return true;
    }

    void queryDevice(int deviceType){
        List<Process> usedProcessList = allProcessMap.values().stream().filter(v -> v.processGroupType == deviceType).collect(Collectors.toList());
    }


    public static class Process {
        int processId;

        // 唯一id
        String uniqueId;

        public int getProcessId() {
            return processId;
        }

        // 进程组类型
        int processGroupType;

        int maxMenSize;

        public int getFreeMenSize() {
            return freeMenSize;
        }

        int freeMenSize;
    }


    public static class Device {
        int deviceId;

        int deviceType;

        int memSize;

        String processUniqueId;

        int processId;
    }
}